package com.zhoufeng.udp.service;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;

import org.apache.log4j.Logger;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.zhoufeng.common.Common;
import com.zhoufeng.model.DeviceConfigure;
import com.zhoufeng.model.DeviceModel;
import com.zhoufeng.model.Recievedata;
import com.zjhbkj.xinfen.model.MsgInfo;
import com.zjhbkj.xinfen.util.CommandUtil;

public class UDPServer extends Thread {
	private static final Logger logger = Logger.getLogger(UDPServer.class);
	private DatagramSocket mReceiveSocket;
	private DatagramSocket mSendSocket;
	private byte[] msg;
	private boolean onGoinglistner;
	
	private boolean flag = true;

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public UDPServer(int port) {
		byte[] arrayOfByte = new byte[Common.COMMAND_LENGTH];
		this.msg = arrayOfByte;
		this.onGoinglistner = true;
		init(port);
	}

	private void init(int port) {
		try {
			if (this.mReceiveSocket == null) {
				DatagramSocket localDatagramSocket1 = new DatagramSocket(null);
				this.mReceiveSocket = localDatagramSocket1;
				this.mReceiveSocket.setReuseAddress(true);
				this.mReceiveSocket.setSoTimeout(10000);
				DatagramSocket localDatagramSocket2 = this.mReceiveSocket;
				int i = port;
				InetSocketAddress localInetSocketAddress = new InetSocketAddress(i);
				localDatagramSocket2.bind(localInetSocketAddress);
			}
			DatagramSocket localDatagramSocket3 = new DatagramSocket();
			this.mSendSocket = localDatagramSocket3;
			return;
		} catch (SocketException localSocketException) {
			String str = localSocketException.toString();
			localSocketException.printStackTrace();
			logger.error(str);
		}
	}

	public void closeConnection() {
		if (this.mReceiveSocket != null) {
			this.mReceiveSocket.close();
			this.mReceiveSocket = null;
		}
		if (this.mSendSocket == null)
			return;
		this.mSendSocket.close();
		this.mSendSocket = null;
	}

	public void run() {
		byte[] arrayOfByte1 = this.msg;
		int i = this.msg.length;
		DatagramPacket localDatagramPacket = new DatagramPacket(arrayOfByte1, i);
		while (flag) {
			if (!this.onGoinglistner)
				return;
			try {
			
				this.mReceiveSocket.receive(localDatagramPacket);
				// RcvComsModel localRcvComsModel = new RcvComsModel();
				byte[] arrayOfByte2 = localDatagramPacket.getData();
				
				String ss = complieData(arrayOfByte2);
				if (ss != null && ss.length() > 65)
					ss = ss.substring(0, 65).trim();

				// boolean bool =
				// localRcvComsModel.receiveCommand(arrayOfByte2);
				if (ss != null && ss.length() == 65) {
					String[] ssarr = ss.split(" ");
					Record modelappmsg = null;
					if ("AA".equals(ssarr[0]) && "EA".equals(ssarr[1])) {
						
						String appmsg = new StringBuffer(ss).replace(18, 23, "%").replace(56, 58, "%").toString();
						if("1".equals(ssarr[4].substring(1))){
							appmsg = new StringBuffer(ss).replace(6, 11, "__ __").replace(18, 23, "__ __").replace(60, 62, "__").toString();
						}else{
							appmsg = new StringBuffer(ss).replace(18, 23, "__ __").replace(60, 62, "__").toString();
						}
						logger.debug("得到的截取字符串后的数据：" + appmsg);
						modelappmsg = Db.findFirst("select *,(select aftersetcount from thing_device_info where id = thing_appmsginfo.id limit 1) serviceaftersetcount from thing_appmsginfo where id=? and appmsg like ? "
								+ " and address = ? and port=?",
								ssarr[19] + ssarr[18] + ssarr[17],appmsg,localDatagramPacket.getAddress().getHostAddress(),localDatagramPacket.getPort()) ;
					
					}
					
					Thread th = new Thread(new UDPProcessThread(localDatagramPacket,modelappmsg));
					th.start();
					
					
					if ("40".equals(ssarr[0]) && "DA".equals(ssarr[1])) {
//						System.out.println("设备来信息了(常规数据)：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						logger.info("设备来信息了(常规数据)(端口："+this.mReceiveSocket.getLocalPort()+")：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						saveDeviceDataAndSendDeviceConfig(localDatagramPacket, ss);
					} else if ("AA".equals(ssarr[0]) && "EA".equals(ssarr[1])) {
//						System.out.println("APP信息了(设置信息)：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						logger.info("APP信息了(设置信息)(端口："+this.mReceiveSocket.getLocalPort()+"：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss + ", IP:" + localDatagramPacket.getAddress().getHostAddress() + ", Port:" + localDatagramPacket.getPort());
						saveDeviceConfigSuccessFlagToAPP(localDatagramPacket, ss,modelappmsg);
					} else if ("AA".equals(ssarr[0]) && "FA".equals(ssarr[1])) {
//						System.out.println("APP信息了(查询数据)：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						
						logger.info("APP信息了(查询数据)(端口："+this.mReceiveSocket.getLocalPort()+"：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						
						//发送设备给的设置信息给APP
						saveDeviceConfigAndSendDeviceDataToAPP(localDatagramPacket, ss);
						//发送服务器所有设置给APP
//						saveDeviceDataAndSendDeviceConfigForApp(localDatagramPacket, ss);
						
					}else if("40".equals(ssarr[0]) && "9A".equals(ssarr[1])){
//						System.out.println("设备信息了(滤网数据)：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						logger.info("设备信息了(滤网数据)(端口："+this.mReceiveSocket.getLocalPort()+"：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						saveDeviceFilterData(localDatagramPacket, ss);
					}else if("AA".equals(ssarr[0]) && "8A".equals(ssarr[1])){
//						System.out.println("APP信息了(滤网数据)：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						logger.info("APP信息了(滤网数据)(端口："+this.mReceiveSocket.getLocalPort()+"：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						saveDeviceFilterSetter(localDatagramPacket, ss);
					}else if("FF".equals(ssarr[0]) && "FF".equals(ssarr[1])){
//						System.out.println("测试信息了：" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						logger.info("测试信息了：(端口："+this.mReceiveSocket.getLocalPort()+"" + "id= " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] +  ", 信息： " + ss );
						sendToMonit(localDatagramPacket);
					}

				} else {
					String send = "数据错误，保存失败！";
					logger.error(send);
//					byte[] bsend = send.getBytes();
//					InetAddress addr = localDatagramPacket.getAddress();
//					int port = localDatagramPacket.getPort();
//					DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
//					this.mReceiveSocket.send(sendPacket);
				}

			}catch (SocketTimeoutException localIOException) {
//				localIOException.printStackTrace();
				//logger.error("接收信息超时：" + localIOException.getMessage());
			} catch (Exception localIOException) {
				localIOException.printStackTrace();
				logger.error("接收处理数据出现错误：" + localIOException.getMessage());

			}
		}
	}

	private void sendToMonit(DatagramPacket localDatagramPacket)  throws IOException {
		boolean bool = true;
		int j = this.msg.length;
		if (bool) {
			// DBMgr.saveModel(localRcvComsModel);
			// EventBus.getDefault().post(localRcvComsModel);
			// send(localDatagramPacket);
			String s = null;
			
			s = "FF FF FE 13 01 11 26 00 35 00 A0 02 5C 15 E9 82 25 FF FF BA 2C AB";
//			if(s == null)
//				s = DeviceConfigure.me.getConfigureinfotoStr(id);
			byte[] bsend = null;
			if (s != null) {
				bsend = CommandUtil.getCommand(s);

				// String send = "接收成功";
				// byte[] bsend = send.getBytes();
				InetAddress addr = localDatagramPacket.getAddress();
				int port = localDatagramPacket.getPort();
				DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
				this.mReceiveSocket.send(sendPacket);
			}
		} else {
			String send = "保存失败";
			byte[] bsend = send.getBytes();
			InetAddress addr = localDatagramPacket.getAddress();
			int port = localDatagramPacket.getPort();
			DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
			this.mReceiveSocket.send(sendPacket);
		}
		
	}

	private void saveDeviceFilterSetter(DatagramPacket localDatagramPacket, String ss) throws IOException {
		boolean bool = true;
		int j = this.msg.length;
		localDatagramPacket.setLength(j);
		if (bool) {
			// DBMgr.saveModel(localRcvComsModel);
			// EventBus.getDefault().post(localRcvComsModel);
			// send(localDatagramPacket);
			String s = null;
			String id = ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17];
			
			s = DeviceModel.me.getFilterSettingsInfoForApp(id);
//			if(s == null)
//				s = DeviceConfigure.me.getConfigureinfotoStr(id);
			byte[] bsend = null;
			if (s != null) {
				bsend = CommandUtil.getCommand(s);

				// String send = "接收成功";
				// byte[] bsend = send.getBytes();
				InetAddress addr = localDatagramPacket.getAddress();
				int port = localDatagramPacket.getPort();
				DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
				this.mReceiveSocket.send(sendPacket);
			}
		} else {
			String send = "保存失败";
			byte[] bsend = send.getBytes();
			InetAddress addr = localDatagramPacket.getAddress();
			int port = localDatagramPacket.getPort();
			DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
			this.mReceiveSocket.send(sendPacket);
		}
	}

	private void saveDeviceFilterData(DatagramPacket localDatagramPacket, String ss) throws IOException {
		//boolean bool = DbMng.saveDeviceFilterData(ss);
		boolean bool = true;
		int j = this.msg.length;
		localDatagramPacket.setLength(j);
		if (bool) {
			// DBMgr.saveModel(localRcvComsModel);
			// EventBus.getDefault().post(localRcvComsModel);
			// send(localDatagramPacket);
			String s = null;
			String id = ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17];
			
			s = DeviceModel.me.getFilterSettingsInfo(id);
			if(s == null)
				s = DeviceConfigure.me.getConfigureinfotoStr(id);
			byte[] bsend = null;
			if (s != null) {
				bsend = CommandUtil.getCommand(s);

				// String send = "接收成功";
				// byte[] bsend = send.getBytes();
				InetAddress addr = localDatagramPacket.getAddress();
				int port = localDatagramPacket.getPort();
				DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
				this.mReceiveSocket.send(sendPacket);
			}
		} else {
			String send = "保存失败";
			byte[] bsend = send.getBytes();
			InetAddress addr = localDatagramPacket.getAddress();
			int port = localDatagramPacket.getPort();
			DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
			this.mReceiveSocket.send(sendPacket);
		}
	}

	/**
	 * 
	 * 接收APP配置信息并发送设备数据信息到APP
	 * 
	 * @param localDatagramPacket
	 * @param ss
	 * @throws IOException
	 */
	private void saveDeviceConfigAndSendDeviceDataToAPP(DatagramPacket localDatagramPacket, String ss) throws IOException {
		//boolean bool = DbMng.saveDeviceConfig(ss);
		boolean bool = true;
		int j = this.msg.length;
		localDatagramPacket.setLength(j);
		if (bool) {
			String s = Recievedata.me.getDeviceDataInfo(ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17],ss);
			logger.debug("服务器-->APP（AA FA的返回）：" + s);
			byte[] bsend = null;
			if (s != null) {
				bsend = CommandUtil.getCommand(s);
				InetAddress addr = localDatagramPacket.getAddress();
				int port = localDatagramPacket.getPort();
				DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
				this.mReceiveSocket.send(sendPacket);
			}
		} else {
			String send = "保存失败";
			byte[] bsend = send.getBytes();
			InetAddress addr = localDatagramPacket.getAddress();
			int port = localDatagramPacket.getPort();
			DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
			this.mReceiveSocket.send(sendPacket);
		}
	}
	
	/**
	 * 
	 * 接收APP配置信息并发送接收配置信息成功提示到APP
	 * 
	 * @param localDatagramPacket
	 * @param ss
	 * @param modelappmsg 
	 * @throws IOException
	 */
	private void saveDeviceConfigSuccessFlagToAPP(DatagramPacket localDatagramPacket, String ss, Record modelappmsg) throws IOException {
		//boolean bool = DbMng.saveDeviceConfig(ss);
		boolean bool = true;
		int j = this.msg.length;
		localDatagramPacket.setLength(j);
		if (bool) {
			//String s = Recievedata.me.getAppSetterSaveSuccessInfo(ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17]);
			String s = Recievedata.me.getDeviceDataInfo(ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17],ss, modelappmsg,localDatagramPacket.getAddress().getHostAddress(),localDatagramPacket.getPort());
//			System.out.println("ID:" + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17]+ ",发送给APP信息：" + s);
//			if("BAFFFF".equals(ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17] )){
				logger.debug("ID:" + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17]+ ",发送给APP信息：" + s);
//			}
			byte[] bsend = null;
			if (s != null) {
				bsend = CommandUtil.getCommand(s);
				InetAddress addr = localDatagramPacket.getAddress();
				int port = localDatagramPacket.getPort();
				DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
				this.mReceiveSocket.send(sendPacket);
			}
		} else {
			String send = "保存失败";
			byte[] bsend = send.getBytes();
			InetAddress addr = localDatagramPacket.getAddress();
			int port = localDatagramPacket.getPort();
			DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
			this.mReceiveSocket.send(sendPacket);
		}
	}

	/**
	 * 
	 * 接收设备数据信息和发送配置到设别
	 * 
	 * @param localDatagramPacket
	 * @param ss
	 * @throws IOException
	 */
	private void saveDeviceDataAndSendDeviceConfig(DatagramPacket localDatagramPacket, String ss) throws IOException {
		//boolean bool = DbMng.saveinfo(ss);
		boolean bool = true;
		int j = this.msg.length;
		localDatagramPacket.setLength(j);
		if (bool) {
			// DBMgr.saveModel(localRcvComsModel);
			// EventBus.getDefault().post(localRcvComsModel);
			// send(localDatagramPacket);
			String s = null;
			String id = ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17];
			
			s = DeviceModel.me.getFilterSettingsInfo(id);
			if(s == null)
				s = DeviceConfigure.me.getConfigureinfotoStr(id, ss);
			
			
			logger.debug("ID: " + ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17]+ ",发送给设备的信息：" + s);
			
			
			byte[] bsend = null;
			if (s != null) {
				bsend = CommandUtil.getCommand(s);

				// String send = "接收成功";
				// byte[] bsend = send.getBytes();
				InetAddress addr = localDatagramPacket.getAddress();
				int port = localDatagramPacket.getPort();
				DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
				this.mReceiveSocket.send(sendPacket);
			}
		} else {
			String send = "保存失败";
			byte[] bsend = send.getBytes();
			InetAddress addr = localDatagramPacket.getAddress();
			int port = localDatagramPacket.getPort();
			DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
			this.mReceiveSocket.send(sendPacket);
		}
	}
	/**
	 * 
	 * 接收设备数据信息和发送配置到APP
	 * 
	 * @param localDatagramPacket
	 * @param ss
	 * @throws IOException
	 */
	private void saveDeviceDataAndSendDeviceConfigForApp(DatagramPacket localDatagramPacket, String ss) throws IOException {
		//boolean bool = DbMng.saveinfo(ss);
		boolean bool = true;
		int j = this.msg.length;
		localDatagramPacket.setLength(j);
		if (bool) {
			// DBMgr.saveModel(localRcvComsModel);
			// EventBus.getDefault().post(localRcvComsModel);
			// send(localDatagramPacket);
			String s = null;
			String id = ss.split(" ")[19] + ss.split(" ")[18] + ss.split(" ")[17];
			
			s = DeviceConfigure.me.getConfigureinfotoStrForApp(id, ss);
			byte[] bsend = null;
			if (s != null) {
				bsend = CommandUtil.getCommand(s);
				
				// String send = "接收成功";
				// byte[] bsend = send.getBytes();
				InetAddress addr = localDatagramPacket.getAddress();
				int port = localDatagramPacket.getPort();
				DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
				this.mReceiveSocket.send(sendPacket);
			}
		} else {
			String send = "保存失败";
			byte[] bsend = send.getBytes();
			InetAddress addr = localDatagramPacket.getAddress();
			int port = localDatagramPacket.getPort();
			DatagramPacket sendPacket = new DatagramPacket(bsend, bsend.length, addr, port);
			this.mReceiveSocket.send(sendPacket);
		}
	}

	private String complieData(byte[] data) {

		String retstr = null;
		retstr = new String(data);
		if (data.length < 65) {
			retstr = CommandUtil.bytesToHexString(data);
		}
		
		if(!checkData(retstr)){
//			logger.error("错误的数据报：" + retstr);
			logger.error("错误的数据报，ID: " + retstr.split(" ")[19] + retstr.split(" ")[18] + retstr.split(" ")[17]+ ",过来数据：" + retstr);
			retstr = null;
		}
		return retstr;
	}
	
	
	private boolean checkData(String retstr){
		boolean flag = false;
		String[] data = retstr.split(" ");
		int sum = 0;
		String num20 = data[20];
		for(int i = 2 ; i < data.length;i++){
			int currentnum = Integer.parseInt(data[i], 16);
			sum += currentnum;
			if( i >= 19){
				break;
			}
		}
		
		String hexsum = Integer.toHexString(sum);
		if(hexsum != null)
			try {
				if(hexsum.length() <= 1){
					hexsum = "0" + hexsum;
				}
				flag = hexsum.toUpperCase().endsWith(num20.toUpperCase());
			} catch (Exception e) {
				e.printStackTrace();
			}
		
		return flag;
	}

//	public void send(DatagramPacket paramDatagramPacket) {
//		SendComsModel localSendComsModel = (SendComsModel) DBMgr.getHistoryData(SendComsModel.class, "EA");
//		if (localSendComsModel == null)
//			return;
//		byte[] arrayOfByte = CommandUtil.getCommand(localSendComsModel.toString());
//		int i = arrayOfByte.length;
//		InetAddress localInetAddress1 = paramDatagramPacket.getAddress();
//		int j = paramDatagramPacket.getPort();
//		DatagramPacket localDatagramPacket = new DatagramPacket(arrayOfByte, i, localInetAddress1, j);
//		try {
//			this.mSendSocket.send(localDatagramPacket);
//			EventBus localEventBus1 = EventBus.getDefault();
//			StringBuilder localStringBuilder1 = new StringBuilder("消息发送成功");
//			InetAddress localInetAddress2 = paramDatagramPacket.getAddress();
//			StringBuilder localStringBuilder2 = localStringBuilder1.append(localInetAddress2).append(":");
//			int k = paramDatagramPacket.getPort();
//			String str1 = new Integer(k).toString();
//			localEventBus1.post(str1);
//			return;
//		} catch (IOException localIOException) {
//			localIOException.printStackTrace();
//			EventBus localEventBus2 = EventBus.getDefault();
//			StringBuilder localStringBuilder3 = new StringBuilder("消息发送失败.");
//			String str2 = localIOException.toString();
//			String str3 = str2;
//			localEventBus2.post(str3);
//		}
//	}

	public void stopAcceptMessage() {
		this.onGoinglistner = false;
	}

	public static abstract interface DataRecvListener {
		public abstract void onRecv(MsgInfo paramMsgInfo);
	}

	public static void main(String[] args) {
		new UDPServer(5000).run();
	}
}